package org.g4studio.core.json;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.Map.Entry;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.g4studio.core.metatype.Dto;
import org.g4studio.core.metatype.impl.BaseDto;
import org.g4studio.core.util.G4Utils;
import org.win.framework.config.bean.CodeValueBean;

/**
 * Json处理器<br>
 * 
 * @xiongchun
 * @since 2009-07-07
 */
public class JsonHelper {

	private static Log log = LogFactory.getLog(JsonHelper.class);

	/**
	 * 将不含日期时间格式的Java对象系列化为Json资料格式
	 * 
	 * @param pObject
	 *            传入的Java对象
	 * @return
	 */
	public static final String encodeObject2Json(Object pObject) {
		String jsonString = "[]";
		if (G4Utils.isEmpty(pObject)) {
			// log.warn("传入的Java对象为空,不能将其序列化为Json资料格式.请检查!");
		} else {
			if (pObject instanceof ArrayList) {
				JSONArray jsonArray = JSONArray.fromObject(pObject);
				jsonString = jsonArray.toString();
			} else {
				JSONObject jsonObject = JSONObject.fromObject(pObject);
				jsonString = jsonObject.toString();
			}
		}
		if (log.isInfoEnabled()) {
			log.info("序列化后的JSON资料输出:\n" + jsonString);
		}
		return jsonString;
	}

	/**
	 * 将含有日期时间格式的Java对象系列化为Json资料格式<br>
	 * Json-Lib在处理日期时间格式是需要实现其JsonValueProcessor接口,所以在这里提供一个重载的方法对含有<br>
	 * 日期时间格式的Java对象进行序列化
	 * 
	 * @param pObject
	 *            传入的Java对象
	 * @return
	 */
	public static final String encodeObject2Json(Object pObject, String pFormatString) {
		String jsonString = "[]";
		if (G4Utils.isEmpty(pObject)) {
			// log.warn("传入的Java对象为空,不能将其序列化为Json资料格式.请检查!");
		} else {
			JsonConfig cfg = new JsonConfig();
			cfg.registerJsonValueProcessor(java.sql.Timestamp.class, new JsonValueProcessorImpl(pFormatString));
			cfg.registerJsonValueProcessor(java.util.Date.class, new JsonValueProcessorImpl(pFormatString));
			cfg.registerJsonValueProcessor(java.sql.Date.class, new JsonValueProcessorImpl(pFormatString));
			if (pObject instanceof ArrayList) {
				JSONArray jsonArray = JSONArray.fromObject(pObject, cfg);
				jsonString = jsonArray.toString();
			} else {
				JSONObject jsonObject = JSONObject.fromObject(pObject, cfg);
				jsonString = jsonObject.toString();
			}
		}
		if (log.isInfoEnabled()) {
			log.info("序列化后的JSON资料输出:\n" + jsonString);
		}
		return jsonString;
	}

	/**
	 * 将分页信息压入JSON字符串
	 * 此类内部使用,不对外暴露
	 * @param JSON字符串
	 * @param totalCount
	 * @return 返回合并后的字符串
	 */
	private static String encodeJson2PageJson(String jsonString, Integer totalCount) {
		jsonString = "{\"TOTALCOUNT\":" + totalCount + ", \"ROOT\":" + jsonString + "}";
		if (log.isInfoEnabled()) {
			log.info("合并后的JSON资料输出:\n" + jsonString);
		}
		return jsonString;
	}

	/**
	 * 直接将List转为分页所需要的Json资料格式
	 * 
	 * @param list
	 *            需要编码的List对象
	 * @param totalCount
	 *            记录总数
	 * @param pDataFormat
	 *            时间日期格式化,传null则表明List不包含日期时间属性
	 */
	public static final String encodeList2PageJson(List list, Integer totalCount, String dataFormat) {
		String subJsonString = "";
		if (G4Utils.isEmpty(dataFormat)) {
			subJsonString = encodeObject2Json(list);
		} else {
			subJsonString = encodeObject2Json(list, dataFormat);
		}
		String jsonString = "{\"TOTALCOUNT\":" + totalCount + ", \"ROOT\":" + subJsonString + "}";
		if (log.isInfoEnabled()) {
			log.info("序列化后的JSON资料输出:\n" + jsonString);
		}
		return jsonString;
	}
	
	
	public static final String encodeComboxJosn(List<CodeValueBean> list) {
		String subJsonString = "";
		for(int i=0;i<list.size();i++){
			CodeValueBean codeValueBean=list.get(i);
			if(i<list.size()-1){
			  subJsonString=subJsonString+"[\""+codeValueBean.getValueCode()+"\",\""+codeValueBean.getValueDisplay()+"\"],";
			}else{
			  subJsonString=subJsonString+"[\""+codeValueBean.getValueCode()+"\",\""+codeValueBean.getValueDisplay()+"\"]";
			}
		}
		return "["+subJsonString+"]";
	}
	
	
	/***
	 * 页面表格或Form需要的表与字段信息
	 * @param list
	 * @param totalCount
	 * @param dataFormat
	 * @return
	 */
	public static final String encodeTableFieldsToJson(List<Map> tabFiels) {
		String subJsonString = "";
		String jsonString ="";
		if(G4Utils.isEmpty(tabFiels)){
			return null;
		}
		for(int i=0;i<tabFiels.size();i++){		
			subJsonString="";
			Map<String,Object> fieldJsonMap =(HashMap<String,Object>)tabFiels.get(i);
			String  tableName=(String)fieldJsonMap.get("tableName");
			Integer totalCount=(Integer)fieldJsonMap.get("totalCount");
			String  dataFormat=(String)fieldJsonMap.get("dataFormat");
			Boolean  expander = (Boolean)fieldJsonMap.get("expander");
			String  queryInfo =(String)fieldJsonMap.get("queryInfo");
			Boolean editFlag = (Boolean)fieldJsonMap.get("editFlag");
			String expandCol = (String)fieldJsonMap.get("expandCol");
			Integer rowFields =(Integer)fieldJsonMap.get("rowFields");
			String url= (String)fieldJsonMap.get("url");
			List<Map<String,Object>> fieldsList = ( ArrayList <Map <String, Object>>)fieldJsonMap.get("fieldsList");
			if (G4Utils.isEmpty(dataFormat)) {
				subJsonString = subJsonString+encodeObject2Json(fieldsList);
			} else {
				subJsonString = subJsonString+encodeObject2Json(fieldsList, dataFormat);
			}
					
			String expanderStr ="\""+"expander"+"\"";					
			String mainJosn=expanderStr+":"+expander;
			
			String queryInfoStr="\"queryInfo\"";
			queryInfo = "\""+queryInfo+"\"";
			mainJosn=mainJosn+","+queryInfoStr+":"+queryInfo;
			
			String urlStr="\"url\"";
			url="\""+url+"\"";	
			mainJosn=mainJosn+","+urlStr+":"+url;			
		
			String editFlagStr="\"editFlag\"";
			mainJosn=mainJosn+","+editFlagStr+":" +editFlag;
			
			String tableCount="\"TOTALCOUNT\"";	
			mainJosn = mainJosn+","+tableCount+":" + totalCount ;
			
			String expandColStr="\"expandCol\"";
			expandCol="\""+expandCol+"\"";
			mainJosn = mainJosn+","+expandColStr+":" + expandCol ;
			
			String rowFieldsStr="\"rowFields\"";
			mainJosn = mainJosn+","+rowFieldsStr+":" + rowFields ;
					
			String tableRoot ="\"ROOT\"";
			subJsonString=mainJosn+","+tableRoot+":"+subJsonString;
			
			tableName ="\""+tableName+"\"";					
			subJsonString = ""+tableName+":{" +subJsonString+"}";
			if(i ==0){
				jsonString=jsonString+subJsonString;
			}else{
				jsonString=jsonString+","+subJsonString;
			}
			
			
		}		
		jsonString = "{"+jsonString+"}";		
		if (log.isInfoEnabled()) {
			log.info("序列化后的JSON资料输出:\n" + jsonString);
		}
		return jsonString;
	}
	
	/**
	 * 查询结果转换为树结点
	 * @param list
	 * @param totalCount
	 * @param dataFormat
	 * @return
	 */
	public static final String encodeList2TreeJson(List list, String dataFormat) {
		String subJsonString = "";
		if (G4Utils.isEmpty(dataFormat)) {
			subJsonString = encodeObject2Json(list);
		} else {
			subJsonString = encodeObject2Json(list, dataFormat);
		}
		String jsonString =  subJsonString ;
		if (log.isInfoEnabled()) {
			log.info("序列化后的JSON资料输出:\n" + jsonString);
		}
		return jsonString;
	}
	/**
	 * 将数据系列化为表单数据填充所需的Json格式
	 * 
	 * @param pObject
	 *            待系列化的对象
	 * @param pFormatString
	 *            日期时间格式化,如果为null则认为没有日期时间型字段
	 * @return
	 */
	public static String encodeDto2FormLoadJson(Dto pDto, String pFormatString) {
		String jsonString = "";
		String sunJsonString = "";
		if (G4Utils.isEmpty(pFormatString)) {
			sunJsonString = encodeObject2Json(pDto);
		} else {
			sunJsonString = encodeObject2Json(pDto, pFormatString);
		}
		jsonString = "{success:"
				+ (G4Utils.isEmpty(pDto.getAsString("success")) ? "true" : pDto.getAsString("success")) + ",data:"
				+ sunJsonString + "}";
		if (log.isInfoEnabled()) {
			log.info("序列化后的JSON资料输出:\n" + jsonString);
		}
		return jsonString;
	}

	/**
	 * 将单一Json对象解析为DTOJava对象
	 * 
	 * @param jsonString
	 *            简单的Json对象
	 * @return dto
	 */
	public static Dto parseSingleJson2Dto(String jsonString) {
		Dto dto = new BaseDto();
		if (G4Utils.isEmpty(jsonString)) {
			return dto;
		}
		JSONObject jb = JSONObject.fromObject(jsonString);
		dto = (BaseDto) JSONObject.toBean(jb, BaseDto.class);
		return dto;
	}

	/**
	 * 将复杂Json资料格式转换为List对象
	 * 
	 * @param jsonString
	 *            复杂Json对象,格式必须符合如下契约<br>
	 *            {"1":{"name":"托尼.贾","age":"27"},
	 *            "2":{"name":"甄子丹","age":"72"}}
	 * @return List
	 */
	public static List parseJson2List(String jsonString) {
		List list = new ArrayList();
		JSONObject jbJsonObject = JSONObject.fromObject(jsonString);			
		Iterator iterator = jbJsonObject.keySet().iterator();
		while (iterator.hasNext()) {
			Dto dto = parseSingleJson2Dto(jbJsonObject.getString(iterator.next().toString()));
			list.add(dto);
		}
		return list;
	}
}
